﻿namespace wwm.LeetCodeHelper.Servers;
public partial class Helper
{
    //public static Dictionary<string, string> cookies = new Dictionary<string, string>();
    public static string cookie_path = "./cookies.txt";
    public static async Task<Dictionary<string, string>> LoginReturnCookies(string username, string password)
    {
        Console.WriteLine("开始使用用户名密码模拟登录获取cookie");
        using var playwright = await Playwright.CreateAsync();
        // 创建Chromium浏览器实例
        await using var browser = await playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions()
        {
            SlowMo = 100,
            Headless = true, // 关闭无头模式(有界面)
            Channel = "chrome", // 指定采用chrome浏览器类型
            Devtools = false, // 启用开发者工具
            ChromiumSandbox = false, // 关闭浏览器沙盒
            ExecutablePath = string.Empty, // 不指定浏览器可执行文件位置，会自动寻找 ms-playwright 下载的浏览器
            Args = new[] { "--enable-automation=true", "--disable-blink-features=AutomationControlled" }, // 防止selenium被检测
        });
        // 浏览器上下文
        await using var context = await browser.NewContextAsync(new BrowserNewContextOptions
        {
            ViewportSize = new ViewportSize
            {
                Width = 1536, // 1920 * 0.8
                Height = 864, // 1080 * 0.8
            }, // 窗口大小
            Locale = "zh-CN", // 指定语言(区域)
            TimezoneId = "Asia/Shanghai", // 指定时区
        });
        //// 使用会话，当state.json文件不存在时会报错
        //await browser.NewContextAsync(new BrowserNewContextOptions
        //{
        //    StorageStatePath = "state.json"
        //});
        //var page = await browser.NewPageAsync();
        // 使用浏览器上下文创建page
        var page = await context.NewPageAsync();
        await page.GotoAsync("https://leetcode-cn.com/accounts/login/", new PageGotoOptions()
        {
            Timeout = 1000 * 60
        });
        //await page.ScreenshotAsync(new PageScreenshotOptions { Path = "screenshot.png" });
        var loginBtn = await page.QuerySelectorAsync("div[data-cypress=sign-in-with-password]");
        if (await loginBtn.InnerTextAsync() == "帐号密码登录")
        {
            await loginBtn.ClickAsync(new ElementHandleClickOptions()
            {
                Delay = new Random().Next(100, 2000)
            });
        }
        await Task.Delay(new Random().Next(100, 2000));
        await page.FillAsync("input[name=login]", username, new PageFillOptions()
        {

        });
        await Task.Delay(new Random().Next(100, 2000));
        await page.FillAsync("input[name=password]", password);
        await Task.Delay(new Random().Next(100, 2000));
        await page.ClickAsync("button[type=submit]");

        await page.WaitForNavigationAsync();
        //await page.ScreenshotAsync(new PageScreenshotOptions { Path = "screenshot.png" });
        // 获取cookies
        var cookies = await context.CookiesAsync();
        Dictionary<string, string> ckis = new Dictionary<string, string>();
        foreach (var cookie in cookies)
        {
            ckis.Add(cookie.Name, cookie.Value);
        }
        // 存储当前会话,会话中右cookie 和 storage内容
        //await context.StorageStateAsync(new BrowserContextStorageStateOptions
        //{
        //    Path = "state.json"
        //});
        return ckis;
    }

    public static async Task<Dictionary<string, string>> GetCookie(string username, string password)
    {
        Dictionary<string, string> cookies = new Dictionary<string, string>();
        if (File.Exists(cookie_path))
        {
            string cookieText = await File.ReadAllTextAsync(cookie_path);
            if (!string.IsNullOrEmpty(cookieText))
            {
                var parseCookie = JsonSerializer.Deserialize<Dictionary<string, string>>(cookieText)!;
                if (parseCookie != null) cookies = parseCookie;
                if (cookies.Count == 0 || !cookies.ContainsKey(Leetcode.leetcode_cookie_session_key) || !cookies.ContainsKey(Leetcode.leetcode_cookie_csrftoken_key))
                {
                    cookies.Clear();
                }
                else
                {
                    //test cookie is not timeout
                    Helper.setCredit(new Credit()
                    {
                        session = cookies[Leetcode.leetcode_cookie_session_key],
                        csrfToken = cookies[Leetcode.leetcode_cookie_csrftoken_key]
                    });
                    var data = await getProfile();
                    if (data == null || data.data == null || data.data.user == null || string.IsNullOrEmpty(data.data.user.username))
                    {
                        cookies.Clear();
                    }
                }
            }
        }
        if (cookies.Count == 0)
        {
            cookies = await LoginReturnCookies(username, password);
            Dictionary<string, string> cookieClone = new Dictionary<string, string>();
            cookieClone.Add(Leetcode.leetcode_cookie_session_key, cookies[Leetcode.leetcode_cookie_session_key]);
            await File.WriteAllTextAsync(cookie_path, JsonSerializer.Serialize(cookieClone));
            return cookies;
        }
        return cookies;
    }

    /// <summary>
    /// 获取用户信息
    /// </summary>
    /// <returns></returns>
    public static async Task<UserProfileRecord> getProfile()
    {
        var response = await Helper.GraphQLRequest(new GraphQLRequestOptions()
        {
            query = @"
            {
                user {
                    username
                }
            }
            "
        });
        return JsonSerializer.Deserialize<UserProfileRecord>(response);
    }
    #region Dtos
    public record UserProfileRecord
    {
        public UserRecord data { get; set; }
    }
    public record UserRecord
    {
        public UserNameRecord user { get; set; }
    }
    public record UserNameRecord
    {
        public string username { get; set; }
    }
    #endregion
}
